//
//  HVideoViewController.m
//  Join
//
//  Created by 黄克瑾 on 2017/1/11.
//  Copyright © 2017年 huangkejin. All rights reserved.
//

#import "HVideoViewController.h"
#import <AVFoundation/AVFoundation.h>
#import "HAVPlayer.h"
#import "HProgressView.h"
#import <Foundation/Foundation.h>
#import <AssetsLibrary/AssetsLibrary.h>
#import "Utility.h"

typedef void(^PropertyChangeBlock)(AVCaptureDevice *captureDevice);

@interface HVideoViewController ()<AVCaptureFileOutputRecordingDelegate>{
    CGFloat topConstraint;      //父视图顶部约束
    CGFloat bottomConstraint;   //父视图底部约束
    CGFloat previewBottmCon;    //视频层底部约束
}

@property (strong, nonatomic)  UIImageView *bgView; //背后的view
@property (strong, nonatomic)  UIButton *btnCamera; //摄像头切换
@property (strong, nonatomic)  UIImageView *focusCursor; //聚焦光标
@property (strong, nonatomic)  UIButton *btnAfresh; //重新录制 （叉叉按钮）
@property (strong, nonatomic)  UIButton *btnEnsure; //确定 （打勾按钮）
@property (strong, nonatomic)  UILabel *labelTipTitle; //轻触拍照，按住摄像
@property (strong, nonatomic)  UIImageView *imgRecord; //拍照、录视频的按钮
@property (strong, nonatomic)  HProgressView *progressView;
@property (strong, nonatomic)  UIButton *btnBack; //返回按钮

@property (strong,nonatomic) AVCaptureMovieFileOutput *captureMovieFileOutput; //视频输出流
//@property (strong,nonatomic) AVCaptureStillImageOutput *captureStillImageOutput;//照片输出流
@property (strong,nonatomic) AVCaptureDeviceInput *captureDeviceInput; //负责从AVCaptureDevice获得输入数据
@property (assign,nonatomic) UIBackgroundTaskIdentifier backgroundTaskIdentifier; //后台任务标识
@property (assign,nonatomic) UIBackgroundTaskIdentifier lastBackgroundTaskIdentifier;
@property(nonatomic)AVCaptureSession *session; //负责输入和输出设备之间的数据传递
@property(nonatomic)AVCaptureVideoPreviewLayer *previewLayer; //图像预览层，实时显示捕获的图像
@property (assign, nonatomic) NSInteger seconds; //记录录制的时间 默认最大60秒
@property (strong, nonatomic) NSURL *saveVideoUrl; //记录需要保存视频的路径
@property (assign, nonatomic) BOOL isFocus; //是否在对焦
@property (strong, nonatomic) HAVPlayer *player; //视频播放
@property (assign, nonatomic) BOOL isVideo; //是否是摄像 YES 代表是录制  NO 表示拍照
@property (strong, nonatomic) UIImage *takeImage;
@property (strong, nonatomic) UIImageView *takeImageView;
@property (nonatomic, strong) PHAsset *vidwoAsset;

@end

#define TimeMax 0.5 //时间大于这个就是视频，否则为拍照

@implementation HVideoViewController

#pragma mark - lifecycle

- (void)viewDidLoad {
    
    [super viewDidLoad];
    id traget = self.navigationController.interactivePopGestureRecognizer.delegate;

    UIPanGestureRecognizer * pan = [[UIPanGestureRecognizer alloc]initWithTarget:traget action:nil];

    [self.view addGestureRecognizer:pan]; //禁止全屏右滑返回
    if (self.HSeconds == 0) {
        self.HSeconds = 10;
    }
    [self layoutViews];
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    self.navigationController.navigationBarHidden = YES;
    [self customCamera];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    self.navigationController.navigationBarHidden = NO;
}

-(void)viewDidDisappear:(BOOL)animated{
    [super viewDidDisappear:animated];
    [self.session stopRunning];
}

#pragma mark - 初始化拍摄
- (void)customCamera {

    //初始化会话，用来结合输入输出
    self.session = [[AVCaptureSession alloc] init];
    //设置分辨率 (设备支持的最高分辨率)
    if ([self.session canSetSessionPreset:AVCaptureSessionPresetHigh]) {
        self.session.sessionPreset = AVCaptureSessionPresetHigh;
    }
    //取得后置摄像头
    AVCaptureDevice *captureDevice = [self getCameraDeviceWithPosition:AVCaptureDevicePositionBack];
    //添加一个音频输入设备
    AVCaptureDevice *audioCaptureDevice=[[AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio] firstObject];
    
    //初始化输入设备
    NSError *error = nil;
    self.captureDeviceInput = [[AVCaptureDeviceInput alloc] initWithDevice:captureDevice error:&error];
    if (error) {
        NSLog(@"取得设备输入对象时出错，错误原因：%@",error.localizedDescription);
        return;
    }
    
    //添加音频
    error = nil;
    AVCaptureDeviceInput *audioCaptureDeviceInput=[[AVCaptureDeviceInput alloc]initWithDevice:audioCaptureDevice error:&error];
    if (error) {
        NSLog(@"取得设备输入对象时出错，错误原因：%@",error.localizedDescription);
        return;
    }
    
    //输出对象
    self.captureMovieFileOutput = [[AVCaptureMovieFileOutput alloc] init];//视频输出
    
    //将输入设备添加到会话
    if ([self.session canAddInput:self.captureDeviceInput]) {
        [self.session addInput:self.captureDeviceInput];
        [self.session addInput:audioCaptureDeviceInput];
        //设置视频防抖
        AVCaptureConnection *connection = [self.captureMovieFileOutput connectionWithMediaType:AVMediaTypeVideo];
        if ([connection isVideoStabilizationSupported]) {
            connection.preferredVideoStabilizationMode = AVCaptureVideoStabilizationModeCinematic;
        }
    }
    
    //将输出设备添加到会话 (刚开始 是照片为输出对象)
    if ([self.session canAddOutput:self.captureMovieFileOutput]) {
        [self.session addOutput:self.captureMovieFileOutput];
    }
    
    //创建视频预览层，用于实时展示摄像头状态
    self.previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session];
    previewBottmCon = IS_IPHONE_X || IS_IPHONE_Xr || IS_IPHONE_Xs_Max ? -88 - 83 : 0;
    self.previewLayer.frame = CGRectMake(0, 0, self.view.qmui_width, kScreenHeight + previewBottmCon);
    self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;//填充模式
    [self.bgView.layer addSublayer:self.previewLayer];
    
    [self addNotificationToCaptureDevice:captureDevice];
    [self addGenstureRecognizer];
    [self.session startRunning];
}

- (void)hiddenTipsLabel {
    self.labelTipTitle.hidden = YES;
}

#pragma mark - 返回
- (void)onCancelAction:(UIButton *)sender {
    [Utility hideProgressDialog];
    [self.navigationController popViewControllerAnimated:NO];
}

#pragma mark - 屏幕点击代理
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    if ([[touches anyObject] view] == self.imgRecord) {

        //根据设备输出获得连接
        AVCaptureConnection *connection = [self.captureMovieFileOutput connectionWithMediaType:AVMediaTypeAudio];
        //根据连接取得设备输出的数据
        if (![self.captureMovieFileOutput isRecording]) {
            
            //如果支持多任务则开始多任务
            if ([[UIDevice currentDevice] isMultitaskingSupported]) {
                self.backgroundTaskIdentifier = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil];
            }
            if (self.saveVideoUrl) {
                [[NSFileManager defaultManager] removeItemAtURL:self.saveVideoUrl error:nil];
            }
            //预览图层和视频方向保持一致
            connection.videoOrientation = [self.previewLayer connection].videoOrientation;
            NSString *outputFielPath=[NSTemporaryDirectory() stringByAppendingString:@"myMovie.mov"];
            NSLog(@"save path is :%@",outputFielPath);
            NSURL *fileUrl=[NSURL fileURLWithPath:outputFielPath];
            NSLog(@"fileUrl:%@",fileUrl);
            [self.captureMovieFileOutput startRecordingToOutputFileURL:fileUrl recordingDelegate:self];
        } else {
            [self.captureMovieFileOutput stopRecording];
        }
    }
}

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    if ([[touches anyObject] view] == self.imgRecord) {
        if (!self.isVideo) {
            [self performSelector:@selector(endRecord) withObject:nil afterDelay:0.3];
        } else {
            [self endRecord];
        }
    }
}

#pragma mark - 开始录制 或 拍照
- (void)onStartTranscribe:(NSURL *)fileURL {
    if ([self.captureMovieFileOutput isRecording]) {
        -- self.seconds;
        if (self.seconds > 0 && self.canTakeVideo) {
            if (self.HSeconds - self.seconds >= TimeMax && !self.isVideo) {
                self.isVideo = YES;//长按时间超过TimeMax 表示是视频录制
                self.progressView.timeMax = self.seconds;
            }
            [self performSelector:@selector(onStartTranscribe:) withObject:fileURL afterDelay:1];
        } else {
            if ([self.captureMovieFileOutput isRecording]) {
                [self.captureMovieFileOutput stopRecording];
            }
        }
    }
}

#pragma mark - 停止录制
- (void)endRecord {
    [self.captureMovieFileOutput stopRecording];
}

#pragma mark - 重新录制
- (void)onAfreshAction:(UIButton *)sender {
    [self recoverLayout];
}

#pragma mark - 确定录制完成 保存视频和图片
- (void)onEnsureAction:(UIButton *)sender {
    
    if([JQLiveTools judgeAuthorization:Authority_Library]){
    
        [self saveVideoOrPhote];
    }else{
        [self executeAlterTips:@"无相册权限，请在iPhone的”设置-隐私-相册“选项中，允许“秒音”访问您的相册"];
    }
}

- (void)saveVideoOrPhote{
    
    __weak __typeof(self)weakSelf = self;
    PHPhotoLibrary *library = [PHPhotoLibrary sharedPhotoLibrary];
    NSError *error = nil;
    __block NSString *assetId = nil;
    
    dispatch_async(dispatch_get_global_queue(0,0), ^{
        
        // 保存资源到【Camera Roll】(相机胶卷)
        [library performChanges:^{
            
            //保存视频
            if (weakSelf.isVideo) {
                assetId = [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:weakSelf.saveVideoUrl].placeholderForCreatedAsset.localIdentifier;
            }
            //保存图片
            else{
                assetId = [PHAssetChangeRequest creationRequestForAssetFromImage:self.takeImage].placeholderForCreatedAsset.localIdentifier;
            }
        } completionHandler:^(BOOL success, NSError * _Nullable error) {
            
            dispatch_async(dispatch_get_main_queue(), ^{
                
                if (success) {
                    
                    //拿到PHAsset文件
                    PHFetchResult *fetchResult = [PHAsset fetchAssetsWithLocalIdentifiers:@[assetId] options:nil];
                    PHAsset *videoAsset = fetchResult.firstObject;
                    //回调
                    [self onCancelAction:nil];
                    if (weakSelf.takeBlock) {
                        weakSelf.takeBlock(weakSelf.takeImage,videoAsset);
                    }
                }else{
                    [MYTipUtils showErrorAlertString:@"保存失败，请重试"];
                    DLog(@"保存资源到本地失败 : %@",error);
                }
            });
        }];
    });
}

//提示弹框
- (void)executeAlterTips:(NSString *)alterTips{
    
    dispatch_async(dispatch_get_main_queue(), ^{
        
        NSString *alterContent = @"提示";
        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:alterContent message:alterTips preferredStyle:(UIAlertControllerStyleAlert)];
        UIAlertAction *action = [UIAlertAction actionWithTitle:@"去设置" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action) {
            
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
        }];
        UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"取消" style:(UIAlertActionStyleCancel) handler:^(UIAlertAction * _Nonnull action) {
            
        }];
        [alertController addAction:cancel];
        [alertController addAction:action];
        [self presentViewController:alertController animated:YES completion:nil];
    });
}


#pragma mark - 前后摄像头的切换
- (void)onCameraAction:(UIButton *)sender {

    AVCaptureDevice *currentDevice=[self.captureDeviceInput device];
    AVCaptureDevicePosition currentPosition=[currentDevice position];
    [self removeNotificationFromCaptureDevice:currentDevice];
    AVCaptureDevice *toChangeDevice;
    AVCaptureDevicePosition toChangePosition = AVCaptureDevicePositionFront;//前
    if (currentPosition == AVCaptureDevicePositionUnspecified || currentPosition == AVCaptureDevicePositionFront) {
        toChangePosition = AVCaptureDevicePositionBack;//后
    }
    toChangeDevice=[self getCameraDeviceWithPosition:toChangePosition];
    [self addNotificationToCaptureDevice:toChangeDevice];
    //获得要调整的设备输入对象
    AVCaptureDeviceInput *toChangeDeviceInput=[[AVCaptureDeviceInput alloc]initWithDevice:toChangeDevice error:nil];
    
    //改变会话的配置前一定要先开启配置，配置完成后提交配置改变
    [self.session beginConfiguration];
    //移除原有输入对象
    [self.session removeInput:self.captureDeviceInput];
    //添加新的输入对象
    if ([self.session canAddInput:toChangeDeviceInput]) {
        [self.session addInput:toChangeDeviceInput];
        self.captureDeviceInput = toChangeDeviceInput;
    }
    //提交会话配置
    [self.session commitConfiguration];
}

#pragma mark - AVCaptureFileOutputRecordingDelegate 视频输出代理
-(void)captureOutput:(AVCaptureFileOutput *)captureOutput didStartRecordingToOutputFileAtURL:(NSURL *)fileURL fromConnections:(NSArray *)connections{

    self.seconds = self.HSeconds;
    [self performSelector:@selector(onStartTranscribe:) withObject:fileURL afterDelay:1];
}

-(void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error{

    [self changeLayout];
    
    if (self.isVideo) {  //视频

        self.saveVideoUrl = outputFileURL;
        if (!self.player) {
            self.player = [[HAVPlayer alloc] initWithFrame:CGRectMake(0, 0, self.view.qmui_width, kScreenHeight + previewBottmCon) withShowInView:self.bgView url:outputFileURL];
            [self.bgView addSubview:self.player];
        } else {
            if (outputFileURL) {
                self.player.videoUrl = outputFileURL;
                self.player.hidden = NO;
            }
        }
        [self handleSourceIsPhoto:NO URL:outputFileURL];
    } else { //照片
        self.saveVideoUrl = nil;
        [self handleSourceIsPhoto:YES URL:outputFileURL];
    }
}

#pragma mark - 处理输出的图片和视频
- (void)handleSourceIsPhoto:(BOOL)isPhoto URL:(NSURL *)url {
    
    AVURLAsset *urlSet = [AVURLAsset assetWithURL:url];
    AVAssetImageGenerator *imageGenerator = [AVAssetImageGenerator assetImageGeneratorWithAsset:urlSet];
    imageGenerator.appliesPreferredTrackTransform = YES;    // 截图的时候调整到正确的方向
    NSError *error = nil;
    CMTime time = CMTimeMake(0,30);//缩略图创建时间 CMTime是表示电影时间信息的结构体，第一个参数表示是视频第几秒，第二个参数表示每秒帧数.(如果要获取某一秒的第几帧可以使用CMTimeMake方法)
    CMTime actucalTime; //缩略图实际生成的时间
    CGImageRef cgImage = [imageGenerator copyCGImageAtTime:time actualTime:&actucalTime error:&error];
    if (error) {
        NSLog(@"截取视频图片失败:%@",error.localizedDescription);
    }
    CMTimeShow(actucalTime);
    UIImage *image = [UIImage imageWithCGImage:cgImage];
    
    CGImageRelease(cgImage);
    if (image) {
        NSLog(@"视频截取成功： %@",image);
    } else {
        NSLog(@"视频截取失败");
    }
    self.takeImage = image;//[UIImage imageWithCGImage:cgImage];
    if (isPhoto) {
        [[NSFileManager defaultManager] removeItemAtURL:url error:nil];
        
        if (!self.takeImageView) {
            self.takeImageView = [[UIImageView alloc] initWithFrame:self.previewLayer.frame];
            self.takeImageView.contentMode = UIViewContentModeScaleAspectFill;
            [self.bgView addSubview:self.takeImageView];
        }
        self.takeImageView.hidden = NO;
        self.takeImageView.image = self.takeImage;
    }
}

#pragma mark - 通知

//注册通知
- (void)setupObservers
{
    NSNotificationCenter *notification = [NSNotificationCenter defaultCenter];
    [notification addObserver:self selector:@selector(applicationDidEnterBackground:) name:UIApplicationWillResignActiveNotification object:[UIApplication sharedApplication]];
}

//进入后台就退出视频录制
- (void)applicationDidEnterBackground:(NSNotification *)notification {
    [self onCancelAction:nil];
}

/**
 *  给输入设备添加通知
 */
-(void)addNotificationToCaptureDevice:(AVCaptureDevice *)captureDevice{
    //注意添加区域改变捕获通知必须首先设置设备允许捕获
    [self changeDeviceProperty:^(AVCaptureDevice *captureDevice) {
        captureDevice.subjectAreaChangeMonitoringEnabled=YES;
    }];
    NSNotificationCenter *notificationCenter= [NSNotificationCenter defaultCenter];
    //捕获区域发生改变
    [notificationCenter addObserver:self selector:@selector(areaChange:) name:AVCaptureDeviceSubjectAreaDidChangeNotification object:captureDevice];
}
-(void)removeNotificationFromCaptureDevice:(AVCaptureDevice *)captureDevice{
    NSNotificationCenter *notificationCenter= [NSNotificationCenter defaultCenter];
    [notificationCenter removeObserver:self name:AVCaptureDeviceSubjectAreaDidChangeNotification object:captureDevice];
}
/**
 *  移除所有通知
 */
-(void)removeNotification{
    NSNotificationCenter *notificationCenter= [NSNotificationCenter defaultCenter];
    [notificationCenter removeObserver:self];
}

-(void)addNotificationToCaptureSession:(AVCaptureSession *)captureSession{
    NSNotificationCenter *notificationCenter= [NSNotificationCenter defaultCenter];
    //会话出错
    [notificationCenter addObserver:self selector:@selector(sessionRuntimeError:) name:AVCaptureSessionRuntimeErrorNotification object:captureSession];
}

/**
 *  设备连接成功
 *
 *  @param notification 通知对象
 */
-(void)deviceConnected:(NSNotification *)notification{
    NSLog(@"设备已连接...");
}
/**
 *  设备连接断开
 *
 *  @param notification 通知对象
 */
-(void)deviceDisconnected:(NSNotification *)notification{
    NSLog(@"设备已断开.");
}
/**
 *  捕获区域改变
 *
 *  @param notification 通知对象
 */
-(void)areaChange:(NSNotification *)notification{
    NSLog(@"捕获区域改变...");
}

/**
 *  会话出错
 *
 *  @param notification 通知对象
 */
-(void)sessionRuntimeError:(NSNotification *)notification{
    NSLog(@"会话发生错误.");
}



/**
 *  取得指定位置的摄像头
 *
 *  @param position 摄像头位置
 *
 *  @return 摄像头设备
 */
-(AVCaptureDevice *)getCameraDeviceWithPosition:(AVCaptureDevicePosition )position{
    NSArray *cameras= [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
    for (AVCaptureDevice *camera in cameras) {
        if ([camera position] == position) {
            return camera;
        }
    }
    return nil;
}

/**
 *  改变设备属性的统一操作方法
 *
 *  @param propertyChange 属性改变操作
 */
-(void)changeDeviceProperty:(PropertyChangeBlock)propertyChange{
    AVCaptureDevice *captureDevice= [self.captureDeviceInput device];
    NSError *error;
    //注意改变设备属性前一定要首先调用lockForConfiguration:调用完之后使用unlockForConfiguration方法解锁
    if ([captureDevice lockForConfiguration:&error]) {
        //自动白平衡
        if ([captureDevice isWhiteBalanceModeSupported:AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance]) {
            [captureDevice setWhiteBalanceMode:AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance];
        }
        //自动根据环境条件开启闪光灯
        if ([captureDevice isFlashModeSupported:AVCaptureFlashModeAuto]) {
            [captureDevice setFlashMode:AVCaptureFlashModeAuto];
        }
        
        propertyChange(captureDevice);
        [captureDevice unlockForConfiguration];
    }else{
        NSLog(@"设置设备属性过程发生错误，错误信息：%@",error.localizedDescription);
    }
}

/**
 *  设置闪光灯模式
 *
 *  @param flashMode 闪光灯模式
 */
-(void)setFlashMode:(AVCaptureFlashMode )flashMode{
    [self changeDeviceProperty:^(AVCaptureDevice *captureDevice) {
        if ([captureDevice isFlashModeSupported:flashMode]) {
            [captureDevice setFlashMode:flashMode];
        }
    }];
}
/**
 *  设置聚焦模式
 *
 *  @param focusMode 聚焦模式
 */
-(void)setFocusMode:(AVCaptureFocusMode )focusMode{
    [self changeDeviceProperty:^(AVCaptureDevice *captureDevice) {
        if ([captureDevice isFocusModeSupported:focusMode]) {
            [captureDevice setFocusMode:focusMode];
        }
    }];
}
/**
 *  设置曝光模式
 *
 *  @param exposureMode 曝光模式
 */
-(void)setExposureMode:(AVCaptureExposureMode)exposureMode{
    [self changeDeviceProperty:^(AVCaptureDevice *captureDevice) {
        if ([captureDevice isExposureModeSupported:exposureMode]) {
            [captureDevice setExposureMode:exposureMode];
        }
    }];
}
/**
 *  设置聚焦点
 *
 *  @param point 聚焦点
 */
-(void)focusWithMode:(AVCaptureFocusMode)focusMode exposureMode:(AVCaptureExposureMode)exposureMode atPoint:(CGPoint)point{
    [self changeDeviceProperty:^(AVCaptureDevice *captureDevice) {
        //聚焦
        if ([captureDevice isFocusModeSupported:focusMode]) {
            [captureDevice setFocusMode:focusMode];
        }
        //聚焦位置
        if ([captureDevice isFocusPointOfInterestSupported]) {
            [captureDevice setFocusPointOfInterest:point];
        }
        //曝光模式
        if ([captureDevice isExposureModeSupported:exposureMode]) {
            [captureDevice setExposureMode:exposureMode];
        }
        //曝光点位置
        if ([captureDevice isExposurePointOfInterestSupported]) {
            [captureDevice setExposurePointOfInterest:point];
        }
    }];
}

/**
 *  添加点按手势，点按时聚焦
 */
-(void)addGenstureRecognizer{
    UITapGestureRecognizer *tapGesture=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapScreen:)];
    [self.bgView addGestureRecognizer:tapGesture];
}

-(void)tapScreen:(UITapGestureRecognizer *)tapGesture{
    if ([self.session isRunning]) {
        CGPoint point= [tapGesture locationInView:self.bgView];
        //将UI坐标转化为摄像头坐标
        CGPoint cameraPoint= [self.previewLayer captureDevicePointOfInterestForPoint:point];
        [self setFocusCursorWithPoint:point];
        [self focusWithMode:AVCaptureFocusModeContinuousAutoFocus exposureMode:AVCaptureExposureModeContinuousAutoExposure atPoint:cameraPoint];
    }
}

/**
 *  设置聚焦光标位置
 *
 *  @param point 光标位置
 */
-(void)setFocusCursorWithPoint:(CGPoint)point{
    if (!self.isFocus) {
        self.isFocus = YES;
        self.focusCursor.center=point;
        self.focusCursor.transform = CGAffineTransformMakeScale(1.4, 1.4);
        self.focusCursor.alpha = 1;
        [UIView animateWithDuration:0.2 animations:^{
            self.focusCursor.transform = CGAffineTransformIdentity;
        } completion:^(BOOL finished) {
            [self performSelector:@selector(onHiddenFocusCurSorAction) withObject:nil afterDelay:0.3];
        }];
    }
}

- (void)onHiddenFocusCurSorAction {
    self.focusCursor.alpha=0;
    self.isFocus = NO;
}

//拍摄完成时调用
- (void)changeLayout {
    self.imgRecord.hidden = YES;
    self.btnCamera.hidden = YES;
    self.btnAfresh.hidden = NO;
    self.btnEnsure.hidden = NO;
    self.btnBack.hidden = YES;
    self.labelTipTitle.hidden = YES;
    if (self.isVideo) {
        [self.progressView clearProgress];
    }

    [self.btnAfresh mas_updateConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(self.view).offset(-110);
    }];

    [self.btnEnsure mas_updateConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(self.view).offset(110);
    }];
    
    
    [UIView animateWithDuration:0.25 animations:^{
        [self.view layoutIfNeeded];
    }];
    
    self.lastBackgroundTaskIdentifier = self.backgroundTaskIdentifier;
    self.backgroundTaskIdentifier = UIBackgroundTaskInvalid;
    [self.session stopRunning];
}

//重新拍摄时调用
- (void)recoverLayout {
    if (self.isVideo) {
        self.isVideo = NO;
        [self.player stopPlayer];
        self.player.hidden = YES;
    }
    [self.session startRunning];

    if (!self.takeImageView.hidden) {
        self.takeImageView.hidden = YES;
    }
//    self.saveVideoUrl = nil;
    self.previewLayer.hidden = NO;
    self.imgRecord.hidden = NO;
    self.btnCamera.hidden = NO;
    self.btnAfresh.hidden = YES;
    self.btnEnsure.hidden = YES;
    self.btnBack.hidden = NO;
    [self.view layoutIfNeeded];
}

#pragma mark - 布局
- (void)layoutViews{
    
    [self.view addSubview:self.bgView];
    self.view.backgroundColor = [UIColor blackColor];
    if(self.canTakeVideo){
        self.labelTipTitle.hidden = NO;
        [self performSelector:@selector(hiddenTipsLabel) withObject:nil afterDelay:4];
    }

    topConstraint = IS_IPHONE_X || IS_IPHONE_Xr || IS_IPHONE_Xs_Max ? 83 : 0;
    bottomConstraint = IS_IPHONE_X || IS_IPHONE_Xr || IS_IPHONE_Xs_Max ? -88 : 0;
    
    [self.bgView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.view).offset(self->topConstraint);
        make.bottom.equalTo(self.view).offset(self->bottomConstraint);
        make.right.left.equalTo(@0);
    }];
    
    [self.view addSubview:self.btnCamera];
    [self.btnCamera mas_makeConstraints:^(MASConstraintMaker *make) {
        
        make.width.height.equalTo(@40);
        make.top.equalTo(self.view).offset(MY_ScaleWidth(35));
        make.right.equalTo(self.view).offset(MY_ScaleWidth(-25));
    }];
    
    [self.view addSubview:self.focusCursor];
    [self.focusCursor mas_makeConstraints:^(MASConstraintMaker *make) {
        
        make.width.height.equalTo(@60);
        make.top.left.equalTo(@0);
    }];
    
    [self.view addSubview:self.labelTipTitle];
    [self.labelTipTitle mas_makeConstraints:^(MASConstraintMaker *make) {
        make.bottom.equalTo(self.view).offset(MY_ScaleWidth(-155));
        make.centerX.equalTo(self.view);
    }];
    
    __block CGFloat btnBottomCon = IS_IPHONE_X ? -120 : -70;
    [self.view addSubview:self.btnAfresh];
    [self.btnAfresh mas_makeConstraints:^(MASConstraintMaker *make) {
        
        make.width.height.equalTo(@70);
        make.bottom.equalTo(self.view).offset(btnBottomCon);
        make.centerX.equalTo(self.view);
    }];
    
    [self.view addSubview:self.btnEnsure];
    [self.btnEnsure mas_makeConstraints:^(MASConstraintMaker *make) {
        
        make.width.height.equalTo(@70);
        make.bottom.equalTo(self.view).offset(btnBottomCon);
        make.centerX.equalTo(self.view);
    }];
    
    [self.view addSubview:self.progressView];
    __block CGFloat progressBottomCon = IS_IPHONE_X ? -100 : -53;
    [self.progressView mas_makeConstraints:^(MASConstraintMaker *make) {
        
        make.width.height.equalTo(@95);
        make.bottom.equalTo(self.view).offset(progressBottomCon);
        make.centerX.equalTo(self.view);
    }];
    
    [self.view addSubview:self.imgRecord];
    [self.imgRecord mas_makeConstraints:^(MASConstraintMaker *make) {
        
        make.width.height.equalTo(@85);
        make.centerX.centerY.equalTo(self.progressView);
    }];
    
    [self.view addSubview:self.btnBack];
    __block CGFloat backBottomCon = IS_IPHONE_X ? -120 : -75;
    [self.btnBack mas_makeConstraints:^(MASConstraintMaker *make) {
        
        make.width.height.equalTo(@45);
        make.left.equalTo(@65);
        make.bottom.equalTo(self.view).offset(backBottomCon);
    }];
}

#pragma mark - lazyload

- (UIImageView *)bgView{
    if(!_bgView){
        _bgView = [[UIImageView alloc]initWithFrame:CGRectZero];
        _bgView.userInteractionEnabled = YES;
    }
    return _bgView;
}

- (UIButton*)btnCamera{
    if(!_btnCamera){
        _btnCamera = [[UIButton alloc]initWithFrame:CGRectZero];
        [_btnCamera setImage:[UIImage imageNamed:@"btn_video_flip_camera.png"] forState:UIControlStateNormal];
        [_btnCamera addTarget:self action:@selector(onCameraAction:) forControlEvents:UIControlEventTouchDown];
    }
    return _btnCamera;
}

- (UIImageView *)focusCursor{
    if(!_focusCursor){
        _focusCursor = [[UIImageView alloc]initWithFrame:CGRectZero];
        _focusCursor.userInteractionEnabled = YES;
        [_focusCursor setImage:[UIImage imageNamed:@"hVideo_focusing"]];
        _focusCursor.alpha=0;
    }
    return _focusCursor;
}

- (UILabel *)labelTipTitle{
    if(!_labelTipTitle){
        _labelTipTitle = [[UILabel alloc]initWithFrame:CGRectZero];
        _labelTipTitle.text = @"轻触拍照,按住摄像";
        _labelTipTitle.font = [UIFont systemFontOfSize:15.0f];
        _labelTipTitle.textColor = [UIColor whiteColor];
        [_labelTipTitle sizeToFit];
        _labelTipTitle.hidden = YES;
    }
    return _labelTipTitle;
}


- (UIButton*)btnAfresh{
    if(!_btnAfresh){
        _btnAfresh = [[UIButton alloc]initWithFrame:CGRectZero];
        [_btnAfresh setImage:[UIImage imageNamed:@"hVideo_cancel"] forState:UIControlStateNormal];
        [_btnAfresh addTarget:self action:@selector(onAfreshAction:) forControlEvents:UIControlEventTouchDown];
    }
    return _btnAfresh;
}

- (UIButton*)btnEnsure{
    if(!_btnEnsure){
        _btnEnsure = [[UIButton alloc]initWithFrame:CGRectZero];
        [_btnEnsure setImage:[UIImage imageNamed:@"hVideo_confirm"] forState:UIControlStateNormal];
        [_btnEnsure addTarget:self action:@selector(onEnsureAction:) forControlEvents:UIControlEventTouchDown];
    }
    return _btnEnsure;
}

- (UIImageView *)imgRecord{
    if(!_imgRecord){
        _imgRecord = [[UIImageView alloc]initWithFrame:CGRectZero];
        _imgRecord.userInteractionEnabled = YES;
        [_imgRecord setImage:[UIImage imageNamed:@"hVideo_take"]];
    }
    return _imgRecord;
}

- (HProgressView *)progressView{
    if(!_progressView){
        _progressView = [[HProgressView alloc]initWithFrame:CGRectZero];
        _progressView.backgroundColor = [UIColor colorWithRed:216/255.0 green:212/255.0 blue:209/255.0 alpha:1];
        _progressView.layer.cornerRadius = 47.5;
        _progressView.layer.masksToBounds = YES;
        _progressView.hidden = YES;
    }
    return _progressView;
}

- (UIButton*)btnBack{
    if(!_btnBack){
        _btnBack = [[UIButton alloc]initWithFrame:CGRectZero];
        [_btnBack setImage:[UIImage imageNamed:@"hVideo_back"] forState:UIControlStateNormal];
        [_btnBack addTarget:self action:@selector(onCancelAction:) forControlEvents:UIControlEventTouchDown];
    }
    return _btnBack;
}

-(void)dealloc{
    [self removeNotification];
}

@end
